/*
 * $Id: NetLinkRoute.cc,v 1.7 2006-01-30 17:38:27 bacon Exp $
 */

#if 0
//#ifdef __linux

#include <xpp/net/NetLinkRoute.h>
#include <xp/bas/memory.h>
#include <xp/bas/errno.h>

namespace xpp
{
	namespace net
	{

		int NetLinkRoute::open ()
		{
			seq = 0;
			return open_with_type (NETLINK_ROUTE);
		}

/*
		int NetLinkRoute::getAddress (int ifce)
		{
			return -1;
		}
*/

		int NetLinkRoute::ask (int family, int type)
		{
			struct sockaddr_nl addr;
			struct {
				struct nlmsghdr h;
				struct rtgenmsg g;
			} req;

			xp_memset (&addr, 0, xp_sizeof(addr));
			addr.nl_family = AF_NETLINK;
			addr.nl_pid = 0;
			addr.nl_groups = 0;
			
			req.h.nlmsg_len = xp_sizeof(req);
			req.h.nlmsg_type = type;
			req.h.nlmsg_flags = NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST;
			req.h.nlmsg_pid = 0;
			req.h.nlmsg_seq = ++seq;	
			req.g.rtgen_family = family;
			
			return xp_scksendto (this->sckhnd, (void*)&req, 
				xp_sizeof(req), 0, (xp_sckadr_t*)&addr, xp_sizeof(addr), -1);
		}

		int NetLinkRoute::dump ()
		{
			char buf[16384];
			struct sockaddr_nl from;
			struct iovec iov = { buf, xp_sizeof(buf) };

			for (;;) {
				struct msghdr msg;
				xp_ssize_t status;

				xp_memset (&msg, 0, xp_sizeof(msg));
				msg.msg_name = &from;
				msg.msg_namelen	 = xp_sizeof(msg);
				msg.msg_iov = &iov;
				msg.msg_iovlen = 1;

				if ((status = recvmsg(this->sckhnd, &msg, 0)) == -1) {
					if (xp_errno == XP_EINTR) continue;
					return -1;
				}
				if (status == 0) return -1;

				if (msg.msg_namelen != xp_sizeof(from)) return -1;

				struct nlmsghdr* h = (struct nlmsghdr*)buf;
				while (NLMSG_OK(h, status)) {
					/*
					if (nladdr.nl_pid != 0 ||
					    h->nlmsg_pid != addr.nl_pid ||
					    h->nlmsg_seq != 	
					*/


					if (h->nlmsg_type == NLMSG_DONE) return 0;
					if (h->nlmsg_type == NLMSG_ERROR) return -1;

					print_ipaddr (&from, h);

					h = NLMSG_NEXT (h, status);
				}

				if (msg.msg_flags & MSG_TRUNC) continue;
			}

			return 0;
		}

#include <xp/bas/stdio.h>
		int NetLinkRoute::print_ipaddr (
			const struct sockaddr_nl* who, struct nlmsghdr* n)
		{
			struct ifaddrmsg* ifa = (struct ifaddrmsg*)NLMSG_DATA(n);	
			int len = n->nlmsg_len;
			int len2;

			len -= NLMSG_LENGTH(xp_sizeof(*ifa));
			if (len < 0) return -1;

			xp_printf (XP_TEXT("%d \n"), ifa->ifa_index);

			struct rtattr* rta = IFA_RTA(ifa);
			len2 = len;
			while (RTA_OK (rta, len2)) {
				if (rta->rta_type == IFA_LABEL) {
					xp_printf (XP_TEXT("label [%S]\n"), RTA_DATA(rta));
				}
				else if (rta->rta_type == IFA_LOCAL) {
					xp_byte_t xxx[4];
					xp_memcpy (xxx, RTA_DATA(rta), RTA_PAYLOAD(rta));
					xp_printf (XP_TEXT("local [%d.%d.%d.%d]\n"), xxx[0], xxx[1], xxx[2], xxx[3]);
				}
				rta = RTA_NEXT(rta,len2);
			}

			xp_printf (XP_TEXT("--------------\n"), ifa->ifa_index);
			return 0;
		}
	}
}

#endif
